

#import "NSDictionary+Utility.h"

@implementation NSMutableDictionary (Utility)


-(void)setObjectIfExisted:(id)object forKey:(id<NSCopying>)key{
    if(object){
        [self setObject:object forKey:key];
    }
}

- (void)setUInteger:(NSUInteger)value forKey:(NSString *)defaultName
{
    [self setObject:[NSString stringWithFormat:@"%zu",(unsigned long)value] forKey:defaultName];
}

- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName
{
    [self setObject:[NSString stringWithFormat:@"%ld",(long)value] forKey:defaultName];
}

- (void)setFloat:(float)value forKey:(NSString *)defaultName
{
    [self setObject:[NSString stringWithFormat:@"%f",(float)value] forKey:defaultName];
}
- (void)setDouble:(double)value forKey:(NSString *)defaultName
{
    [self setObject:[NSString stringWithFormat:@"%lf",(double)value] forKey:defaultName];
}
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName
{
    if(value)
        [self setObject:@"1" forKey:defaultName];
    else
        [self setObject:@"0" forKey:defaultName];
}



- (void)addObject:(nullable id)anObject forKey:(nonnull id <NSCopying>)aKey
{
    if(!anObject || !aKey)
        return;
    
    NSMutableArray *ma = [self objectForKey:aKey];
    if(![ma isKindOfClass:[NSMutableArray class]])
    {
        id preObj = ma;
        ma = [NSMutableArray arrayWithCapacity:5];
        [self setObject:ma forKey:aKey];
        if(preObj)
            [ma addObject:preObj];
    }
    
    [ma addObject:anObject];
}

-(void)addUniqueObject:(nullable id)anObject forKey:(nonnull id <NSCopying>)aKey
{
    if(!anObject || !aKey)
        return;
    
    NSMutableArray *ma = [self objectForKey:aKey];
    if(![ma isKindOfClass:[NSMutableArray class]])
    {
        id preObj = ma;
        ma = [NSMutableArray arrayWithCapacity:5];
        [self setObject:ma forKey:aKey];
        if(preObj)
            [ma addObject:preObj];
    }
    
    BOOL add = YES;
    for(id obj in ma)
    {
        if([obj isEqual:anObject])
        {
            add = NO;
            break;
        }
    }
    if(add)
        [ma addObject:anObject];
}

- (void)removeObject:(nonnull id)anObject forKey:(nonnull id <NSCopying>)aKey
{
    NSMutableArray *ma = [self objectForKey:aKey];
    if([ma isKindOfClass:[NSMutableArray class]])
    {
        [ma removeObject:anObject];
        if(ma.count == 0)
            [self removeObjectForKey:aKey];
    }
}

- (void)removeAllObjectsForKey:(nonnull id <NSCopying>)aKey
{
    [self removeObjectForKey:aKey];
}

- (nullable NSArray *)objectsForKey:(nonnull id <NSCopying>)aKey
{
    NSMutableArray *ma = [self objectForKey:aKey];
    if(!ma)
        return nil;
    
    if([ma isKindOfClass:[NSMutableArray class]])
        return [NSArray arrayWithArray:ma];
    else
        return [NSArray arrayWithObject:ma];
}

-(void)removeRedundantObjects {
    
    @synchronized(self)
    {
        NSMutableArray *mKeysToRemove = [NSMutableArray arrayWithCapacity:self.count];
        
        [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            CFIndex retainCount = CFGetRetainCount((__bridge CFTypeRef)obj);
            if(retainCount <= 2)//因为enumerateKeysAndObjectsUsingBlock方法会把对象传给形参，形参会被objc_msgSend()函数retain,所以这里的retainCount为2即表示没有其他外部引用
            {
                [mKeysToRemove addObject:key];
            }
        }];
        
        [self removeObjectsForKeys:mKeysToRemove];
    }
}


@end

@implementation NSDictionary (Utility)

-(int64_t)longLongValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])
    {
        return [obj longLongValue];
    }
    return 0;
}
-(int32_t)intValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])
    {
        return [obj intValue];
    }
    return 0;
}

-(int16_t)shortValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSNumber class]])
    {
        return [obj shortValue];
    }else if ([obj isKindOfClass:[NSString class]]){
        return (int16_t)[(NSString *)obj intValue];
    }
    return 0;
}
-(int8_t)charValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ( [obj isKindOfClass:[NSNumber class]])
    {
        return [obj charValue];
    }else if ([obj isKindOfClass:[NSString class]]){
        return (int8_t)[(NSString *)obj intValue];
    }
    return 0;
}

- (uint8_t)unsignedCharValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ( [obj isKindOfClass:[NSNumber class]])
    {
        return [obj unsignedCharValue];
    }else if ([obj isKindOfClass:[NSString class]]){
        return (uint8_t)[(NSString *)obj intValue];
    }
    return 0;

}
-(BOOL)boolValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])
    {
        return [obj boolValue];
    }
    return 0;
}

-(double)doubleValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])
    {
        return [obj doubleValue];
    }
    return 0;
}

-(float)floatValueForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])
    {
        return [obj floatValue];
    }
    return 0;
}

-(NSString *)stringForKey:(id)key
{
    id obj = [self objectForKey:key];
    if ([obj isKindOfClass:[NSNull class]]) {
        return nil;
    }
    if ([obj isKindOfClass:[NSString class]]) {
        return obj;
    }
    if ([obj isKindOfClass:[NSNumber class]]) {
        return [NSString stringWithFormat:@"%@",obj];
    }
    return nil;
}

- (NSInteger)integerForKey:(NSString *)defaultName
{
    return [self longLongValueForKey:defaultName];
}
- (float)floatForKey:(NSString *)defaultName
{
    return [self floatValueForKey:defaultName];
}
- (double)doubleForKey:(NSString *)defaultName
{
    return [self doubleValueForKey:defaultName];
}
- (BOOL)boolForKey:(NSString *)defaultName
{
    return [self boolValueForKey:defaultName];
}





-(NSString *)jsonString
{
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                         error:nil];
    if (! jsonData)
        return nil;
    else
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
}


+(NSDictionary *)parametersFromQuery:(NSString *)query{
    
    NSArray * parameterStringArray = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary * paramDict = [[NSMutableDictionary alloc] initWithCapacity:parameterStringArray.count];
    for (NSString * paramString in parameterStringArray) {
        
        NSScanner *scanner = [NSScanner scannerWithString:paramString];
        
        NSString *key, *value;
        [scanner scanUpToString:@"=" intoString:&key];
        [scanner scanString:@"=" intoString:nil];
        [scanner scanUpToString:@"" intoString:&value];
        if(key && value)
            [paramDict setObject:value forKey:key];
    }
    return paramDict;
}

//通过json字符串获取字典
+(NSDictionary *)dictWithJsonString:(NSString *)string
{
    if (string == nil || ![string isKindOfClass:[NSString class]]) {
        return nil;
    }
    
    NSData *jsonData = [string dataUsingEncoding:NSUTF8StringEncoding];
    
    NSError *err;
    
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
    
    if(err) {
        
        return nil;
    }
    
    return dic;
}

@end

